From b5d6ea35c066ae05e1c353f5c6df0e207651d44c Mon Sep 17 00:00:00 2001 From: tsteven4 Date: Tue, 13 Aug 2013 02:09:20 +0000 Subject: [PATCH] subclass QFile to provide error handling and stdio. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@4531 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/Makefile.in | 8 ++-- gpsbabel/geo.cc | 4 +- gpsbabel/gpx.cc | 12 ++---- gpsbabel/kml.cc | 11 ++---- gpsbabel/reference/nonexistent.err | 1 + gpsbabel/src/core/file.h | 60 ++++++++++++++++++++++++++++++ gpsbabel/testo.d/geo.test | 5 +++ gpsbabel/testo.d/gpx.test | 5 +++ gpsbabel/testo.d/kml.test | 4 ++ gpsbabel/testo.d/xol.test | 15 ++++++++ gpsbabel/xmlgeneric.cc | 4 +- 11 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 gpsbabel/reference/nonexistent.err create mode 100644 gpsbabel/src/core/file.h diff --git a/gpsbabel/Makefile.in b/gpsbabel/Makefile.in index e30243ae5..83e6735df 100644 --- a/gpsbabel/Makefile.in +++ b/gpsbabel/Makefile.in @@ -599,7 +599,7 @@ gdb.o: gdb.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ garmin_tables.h grtcirc.h geo.o: geo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \ - cet.h cet_util.h inifile.h session.h src/core/datetime.h + cet.h cet_util.h inifile.h session.h src/core/datetime.h src/core/file.h geoniche.o: geoniche.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \ gbfile.h cet.h cet_util.h inifile.h session.h src/core/datetime.h \ pdbfile.h jeeps/gpsmath.h jeeps/gps.h jeeps/gpsport.h \ @@ -654,7 +654,7 @@ gpx.o: gpx.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \ jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ - src/core/xmlstreamwriter.h + src/core/xmlstreamwriter.h src/core/file.h grtcirc.o: grtcirc.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \ gbfile.h cet.h cet_util.h inifile.h session.h src/core/datetime.h \ grtcirc.h @@ -834,7 +834,7 @@ jtr.o: jtr.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \ cet.h cet_util.h inifile.h session.h src/core/datetime.h csv_util.h kml.o: kml.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \ cet.h cet_util.h inifile.h session.h src/core/datetime.h xmlgeneric.h \ - grtcirc.h src/core/xmlstreamwriter.h + grtcirc.h src/core/xmlstreamwriter.h src/core/file.h lmx.o: lmx.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \ cet.h cet_util.h inifile.h session.h src/core/datetime.h xmlgeneric.h lowranceusr.o: lowranceusr.cc defs.h config.h queue.h zlib/zlib.h \ @@ -1157,7 +1157,7 @@ xcsv.o: xcsv.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \ xhtmlent.o: xhtmlent.cc xmlgeneric.o: xmlgeneric.cc defs.h config.h queue.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h session.h \ - src/core/datetime.h xmlgeneric.h + src/core/datetime.h xmlgeneric.h src/core/file.h xmltag.o: xmltag.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \ gbfile.h cet.h cet_util.h inifile.h session.h src/core/datetime.h xol.o: xol.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \ diff --git a/gpsbabel/geo.cc b/gpsbabel/geo.cc index 302b47a30..fea6fa7f5 100644 --- a/gpsbabel/geo.cc +++ b/gpsbabel/geo.cc @@ -24,10 +24,10 @@ static char* nuke_placer; static gbfile* ofd; -#include #include #include #include +#include "src/core/file.h" QString ostring; QXmlStreamWriter writer(&ostring); @@ -117,7 +117,7 @@ geo_rd_init(const char* fname) static void geo_read(void) { - QFile file(geo_read_fname); + gpsbabel::File file(geo_read_fname); file.open(QIODevice::ReadOnly); reader.setDevice(&file); diff --git a/gpsbabel/gpx.cc b/gpsbabel/gpx.cc index cb4688cb6..e9c247aab 100644 --- a/gpsbabel/gpx.cc +++ b/gpsbabel/gpx.cc @@ -27,8 +27,8 @@ #include static XML_Parser psr; #endif +#include "src/core/file.h" #include "src/core/xmlstreamwriter.h" -#include #include #include #include @@ -56,8 +56,7 @@ static UrlLink* link_; static int cache_descr_is_html; static gbfile* fd; static const char* input_fname; -static gbfile* ofd = NULL; -static QFile* oqfile; +static gpsbabel::File* oqfile; static gpsbabel::XmlStreamWriter* writer; static short_handle mkshort_handle; static const char* link_url; @@ -1364,9 +1363,8 @@ gpx_wr_init(const char* fname) { mkshort_handle = NULL; // QFile requires binary mode on Windows. - ofd = gbfopen(fname, "wb", MYNAME); - oqfile = new QFile; - oqfile->open(ofd->handle.std, QIODevice::WriteOnly); + oqfile = new gpsbabel::File(fname); + oqfile->open(QIODevice::WriteOnly); writer = new gpsbabel::XmlStreamWriter(oqfile); writer->setAutoFormattingIndent(2); @@ -1383,8 +1381,6 @@ gpx_wr_deinit(void) oqfile->close(); delete oqfile; oqfile = NULL; - gbfclose(ofd); - ofd = NULL; mkshort_del_handle(&mkshort_handle); } diff --git a/gpsbabel/kml.cc b/gpsbabel/kml.cc index ae39eddf9..62bc47343 100644 --- a/gpsbabel/kml.cc +++ b/gpsbabel/kml.cc @@ -32,6 +32,7 @@ #include "xmlgeneric.h" #include "grtcirc.h" +#include "src/core/file.h" #include "src/core/xmlstreamwriter.h" // options @@ -67,8 +68,7 @@ static int wpt_tmp_queued; static const char* posnfilename; static char* posnfilenametmp; -static gbfile* ofd = NULL; -static QFile* oqfile; +static gpsbabel::File* oqfile; static gpsbabel::XmlStreamWriter* writer; typedef enum { @@ -436,9 +436,8 @@ kml_wr_init(const char* fname) /* * Reduce race conditions with network read link. */ - ofd = gbfopen(fname, "w", MYNAME); - oqfile = new QFile; - oqfile->open(ofd->handle.std, QIODevice::WriteOnly); + oqfile = new gpsbabel::File(fname); + oqfile->open(QIODevice::WriteOnly); writer = new gpsbabel::XmlStreamWriter(oqfile); writer->setAutoFormattingIndent(2); @@ -475,8 +474,6 @@ kml_wr_deinit(void) oqfile->close(); delete oqfile; oqfile = NULL; - gbfclose(ofd); - ofd = NULL; if (posnfilenametmp) { #if __WIN32__ diff --git a/gpsbabel/reference/nonexistent.err b/gpsbabel/reference/nonexistent.err new file mode 100644 index 000000000..6a9909604 --- /dev/null +++ b/gpsbabel/reference/nonexistent.err @@ -0,0 +1 @@ +Cannot open './reference/doesnotexist' for read. Error was 'No such file or directory'. diff --git a/gpsbabel/src/core/file.h b/gpsbabel/src/core/file.h new file mode 100644 index 000000000..d01d6dd4f --- /dev/null +++ b/gpsbabel/src/core/file.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2013 Robert Lipe, gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include +#include "defs.h" + +// Mimic gbfile open services + +namespace gpsbabel +{ + +class File : public QFile +{ +public: + File(const QString& s) : QFile(s) {} + + /* in the tradition of gbfile we assume WriteOnly or ReadOnly, not ReadWrite */ + bool open(OpenMode mode) { + bool status; + + if (QFile::fileName() == "-") { + if (mode & QIODevice::WriteOnly) { + status = QFile::open(stdout, mode); + } else { + status = QFile::open(stdin, mode); + } + } else { + status = QFile::open(mode); + } + + if (!status) { + fatal("Cannot open '%s' for %s. Error was '%s'.\n", + CSTR(QFile::fileName()), + mode == QIODevice::WriteOnly? "write" : "read", + CSTR(QFile::errorString())); + } + return status; + } + +}; + +}; // namespace gpsbabel diff --git a/gpsbabel/testo.d/geo.test b/gpsbabel/testo.d/geo.test index d5752a67e..c5dbe7978 100644 --- a/gpsbabel/testo.d/geo.test +++ b/gpsbabel/testo.d/geo.test @@ -3,3 +3,8 @@ rm -f ${TMPDIR}/gl.loc gpsbabel -i geo -f ${REFERENCE}/../geocaching.loc -o geo -F ${TMPDIR}/gl.loc compare ${TMPDIR}/gl.loc ${REFERENCE} + +# we have a one off reader in geo, make sure it can read stdin. +rm -f ${TMPDIR}/gl_si.loc +cat ${REFERENCE}/../geocaching.loc | gpsbabel -i geo -f - -o geo -F ${TMPDIR}/gl_si.loc +compare ${TMPDIR}/gl_si.loc ${REFERENCE}/gl.loc diff --git a/gpsbabel/testo.d/gpx.test b/gpsbabel/testo.d/gpx.test index e4fd6b5f3..85d29e943 100644 --- a/gpsbabel/testo.d/gpx.test +++ b/gpsbabel/testo.d/gpx.test @@ -25,3 +25,8 @@ compare ${REFERENCE}/extensiondata~unicsv.gpx ${TMPDIR}/extensiondata.gpx # Read, write GPX file with times that don't fit in time_t, subsecond. gpsbabel -i gpx -f ${REFERENCE}/bigtime.gpx -o gpx -F ${TMPDIR}/bigtime.gpx compare ${REFERENCE}/bigtime.gpx ${TMPDIR}/bigtime.gpx + +# test standard output +rm -f ${TMPDIR}/basecamp~gpx_so.gpx +gpsbabel -i gpx -f ${REFERENCE}/basecamp.gpx -o gpx -F - 1> ${TMPDIR}/basecamp~gpx_so.gpx +compare ${REFERENCE}/basecamp~gpx.gpx ${TMPDIR}/basecamp~gpx_so.gpx diff --git a/gpsbabel/testo.d/kml.test b/gpsbabel/testo.d/kml.test index c4463c04a..74a59f862 100644 --- a/gpsbabel/testo.d/kml.test +++ b/gpsbabel/testo.d/kml.test @@ -52,6 +52,10 @@ gpsbabel -i gpx -f ${REFERENCE}/expertgps.gpx -o kml,track=1 \ compare ${TMPDIR}/ge-eg-track1.kml ${TMPDIR}/ge-eg-track2.kml compare ${TMPDIR}/ge-eg-track2.kml ${TMPDIR}/ge-eg-track3.kml +# test std output +rm -f ${TMPDIR}/bnds_so.kml +gpsbabel -i gpx -f ${REFERENCE}/bounds-test.gpx -o kml -F - 1> ${TMPDIR}/bnds_so.kml +compare ${REFERENCE}/bounds-test.kml ${TMPDIR}/bnds_so.kml set -e if which xmllint > /dev/null; diff --git a/gpsbabel/testo.d/xol.test b/gpsbabel/testo.d/xol.test index b29992fb5..d63f16cd5 100644 --- a/gpsbabel/testo.d/xol.test +++ b/gpsbabel/testo.d/xol.test @@ -4,6 +4,21 @@ gpsbabel -i xol -f ${REFERENCE}/xol-sample.xol -o gpx -F ${TMPDIR}/xol-sample.gpx compare ${REFERENCE}/xol-sample.gpx ${TMPDIR}/xol-sample.gpx +# check xmlgeneric can handle stdin +rm -f ${TMPDIR}/xol-sample.gpx +cat ${REFERENCE}/xol-sample.xol | gpsbabel -i xol -f - -o gpx -F ${TMPDIR}/xol-sample.gpx +compare ${REFERENCE}/xol-sample.gpx ${TMPDIR}/xol-sample.gpx + +# check xmlgeneric can detect no input file +# we expect this to fail +rm -f ${TMPDIR}/xol-sample_si.gpx +${PNAME} -i xol -f ${REFERENCE}/doesnotexist -o gpx -F ${TMPDIR}/xol-sample_si.gpx 2> ${TMPDIR}/nonexistent.err && { + echo "${PNAME} succeeded! (it shouldn't have with this input...)" +} +# check error message is what we expected +compare ${REFERENCE}/nonexistent.err ${TMPDIR}/nonexistent.err + + gpsbabel -i gpx -f ${REFERENCE}/xol-sample.gpx -o xol -F ${TMPDIR}/xol-sample-gpx.xol compare ${REFERENCE}/xol-sample-gpx.xol ${TMPDIR}/xol-sample-gpx.xol diff --git a/gpsbabel/xmlgeneric.cc b/gpsbabel/xmlgeneric.cc index abd712d16..4860e9fde 100644 --- a/gpsbabel/xmlgeneric.cc +++ b/gpsbabel/xmlgeneric.cc @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include "defs.h" #include "xmlgeneric.h" #include "cet_util.h" +#include "src/core/file.h" #define DEBUG_TAG 0 #if DEBUG_TAG @@ -255,7 +255,7 @@ readnext: void xml_read(void) { - QFile file(rd_fname); + gpsbabel::File file(rd_fname); QString current_tag; file.open(QIODevice::ReadOnly); -- 2.30.2